Skip to content

test: add RDC_DATA_DIR seam and centralize unit/e2e home isolation#251

Merged
BANANASJIM merged 5 commits into
masterfrom
fix/rdc-test-isolation
Jun 23, 2026
Merged

test: add RDC_DATA_DIR seam and centralize unit/e2e home isolation#251
BANANASJIM merged 5 commits into
masterfrom
fix/rdc-test-isolation

Conversation

@BANANASJIM

@BANANASJIM BANANASJIM commented Jun 16, 2026

Copy link
Copy Markdown
Owner

_platform.data_dir() had no env override, so test isolation was 33 hand-copied monkeypatch seams across 14 unit files, and the e2e suite ran the real CLI against the developer's real ~/.rdc (leaking sessions and live daemons on failed teardown).

  • Adds an additive RDC_DATA_DIR override to data_dir() (production default unchanged; renderdoc-lib discovery untouched).
  • Replaces the 33 duplicated seams with one autouse fixture in tests/unit/conftest.py.
  • e2e: threads an isolated data dir into every subprocess, session-scoped, with crash-safe daemon reaping.
  • Tightens an over-broad "localhost" not in str(path) assertion in test_remote_core.py that broke once the data dir moved under a tmp path whose node-id contains "localhost" (the exact filename assertion is kept).

Regression tests fail without the seam (verified). Unit suite 2995 passed.

Summary by CodeRabbit

  • New Features
    • The data directory path can now be customized via the RDC_DATA_DIR environment variable. When set, this variable overrides platform-specific default locations. If unset or empty, the system falls back to the default directory, maintaining backward compatibility.

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@BANANASJIM, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 43 minutes and 41 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses rolling per-developer review limits. Reviews become available again as older review attempts age out of the rolling limit window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c60af597-62c1-4e9f-a653-e0a9d3eb4ee8

📥 Commits

Reviewing files that changed from the base of the PR and between e3f3b2e and 466408b.

📒 Files selected for processing (2)
  • src/rdc/_platform.py
  • tests/unit/test_platform.py
📝 Walkthrough

Walkthrough

data_dir() in _platform.py gains an RDC_DATA_DIR environment variable override. A new autouse fixture in tests/unit/conftest.py centralizes data-dir isolation by setting this env var and patching data_dir for every unit test, replacing ~15 per-file _isolate_home fixtures. E2e helpers propagate the env to subprocesses and add daemon-reaping teardown.

Changes

RDC_DATA_DIR env override and centralized test isolation

Layer / File(s) Summary
data_dir() RDC_DATA_DIR env override
src/rdc/_platform.py, tests/unit/test_platform.py
data_dir() returns Path(RDC_DATA_DIR) when the env var is set; new tests cover override precedence, empty-env fallback, and a session save/load round-trip under the override.
Centralized unit test autouse isolation fixture
tests/unit/conftest.py
New _isolate_data_dir autouse fixture creates tmp_path/.rdc, exports RDC_DATA_DIR for subprocesses, and monkeypatches rdc._platform.data_dir in-process for every unit test.
Remove per-module _isolate_home fixtures from unit tests
tests/unit/test_android_commands.py, tests/unit/test_capture_control.py, tests/unit/test_cli_session_flag.py, tests/unit/test_keep_remote.py, tests/unit/test_remote_commands.py, tests/unit/test_remote_core.py, tests/unit/test_remote_state.py, tests/unit/test_remote_status_disconnect.py, tests/unit/test_session_commands.py, tests/unit/test_session_service.py, tests/unit/test_session_state.py, tests/unit/test_shader_preload.py, tests/unit/test_split_core.py, tests/unit/test_target_state.py
Deletes all per-module _isolate_home autouse fixtures and inline monkeypatch.setattr("rdc._platform.data_dir", ...) calls. _setup_data_dir in test_session_commands.py no longer patches data_dir. test_parsed_localhost_keys_on_ipv4 assertion updated to check path.parent.name instead of the absolute path string.
E2e subprocess env propagation and session teardown
tests/e2e/e2e_helpers.py, tests/e2e/conftest.py
Adds SUBPROCESS_ENV/_subprocess_env() so all CLI subprocess invocations carry the merged env including RDC_DATA_DIR. _isolate_e2e_data_dir sets and clears RDC_DATA_DIR and calls _reap_daemons() on teardown. Session-opening fixtures (captured_rdc, can_replay_prerecorded, vkcube_session, dynamic_session, oit_session) wrapped in try/finally to guarantee rdc close on teardown.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • BANANASJIM/rdc-cli#124: Introduces data_dir() in src/rdc/_platform.py; this PR extends that same function to honor the RDC_DATA_DIR environment variable override.

Suggested labels

Review effort 3/5

🐇 A bunny hopped through the code one day,
And found a dozen fixtures strewn about the way.
"One conftest to rule them all!" it declared with glee,
Now RDC_DATA_DIR sets the path—no duplicates, you see!
A tidy warren, test by test, isolated and free. 🌿

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding an RDC_DATA_DIR environment variable seam and centralizing home directory isolation in tests.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/rdc-test-isolation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/e2e/conftest.py (1)

40-48: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding logging to _reap_daemons for observability.

The daemon cleanup is a critical part of test isolation. Adding log messages when a daemon is successfully terminated (or termination fails) would improve debugging when cleanup doesn't work as expected.

📊 Proposed logging additions
 def _reap_daemons(data_dir: Path) -> None:
     """Terminate any daemons still recorded under *data_dir* (best effort)."""
     for session_file in data_dir.glob("sessions/*.json"):
         try:
             pid = int(json.loads(session_file.read_text()).get("pid", 0))
         except (OSError, ValueError, TypeError, json.JSONDecodeError):
             continue
         if pid > 0 and _platform.is_pid_alive(pid):
-            _platform.terminate_process_tree(pid)
+            if _platform.terminate_process_tree(pid):
+                _log.info("Terminated daemon PID %d from session %s", pid, session_file.name)
+            else:
+                _log.warning("Failed to terminate daemon PID %d from session %s", pid, session_file.name)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/e2e/conftest.py` around lines 40 - 48, Add logging to the _reap_daemons
function to improve observability of daemon cleanup operations. Include log
messages when a daemon process is successfully terminated via
_platform.terminate_process_tree(pid), and also add logging when termination
fails or encounters errors. This will help with debugging when test cleanup
doesn't work as expected.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/e2e/conftest.py`:
- Around line 40-48: Add logging to the _reap_daemons function to improve
observability of daemon cleanup operations. Include log messages when a daemon
process is successfully terminated via _platform.terminate_process_tree(pid),
and also add logging when termination fails or encounters errors. This will help
with debugging when test cleanup doesn't work as expected.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e7e893dd-a00f-424e-b5a2-c7feea28482a

📥 Commits

Reviewing files that changed from the base of the PR and between 805efa1 and e3f3b2e.

📒 Files selected for processing (20)
  • src/rdc/_platform.py
  • tests/e2e/conftest.py
  • tests/e2e/e2e_helpers.py
  • tests/unit/conftest.py
  • tests/unit/test_android_commands.py
  • tests/unit/test_capture_control.py
  • tests/unit/test_cli_session_flag.py
  • tests/unit/test_keep_remote.py
  • tests/unit/test_platform.py
  • tests/unit/test_remote_commands.py
  • tests/unit/test_remote_core.py
  • tests/unit/test_remote_setup.py
  • tests/unit/test_remote_state.py
  • tests/unit/test_remote_status_disconnect.py
  • tests/unit/test_session_commands.py
  • tests/unit/test_session_service.py
  • tests/unit/test_session_state.py
  • tests/unit/test_shader_preload.py
  • tests/unit/test_split_core.py
  • tests/unit/test_target_state.py
💤 Files with no reviewable changes (13)
  • tests/unit/test_remote_commands.py
  • tests/unit/test_remote_state.py
  • tests/unit/test_keep_remote.py
  • tests/unit/test_android_commands.py
  • tests/unit/test_split_core.py
  • tests/unit/test_shader_preload.py
  • tests/unit/test_remote_status_disconnect.py
  • tests/unit/test_remote_setup.py
  • tests/unit/test_cli_session_flag.py
  • tests/unit/test_session_state.py
  • tests/unit/test_session_service.py
  • tests/unit/test_capture_control.py
  • tests/unit/test_target_state.py

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@BANANASJIM BANANASJIM merged commit 70aabfc into master Jun 23, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant